package com.qlu.syq.aspectj;

import cn.hutool.core.text.StrFormatter;
import com.qlu.syq.entity.BaseEntity;
import com.qlu.syq.entity.admin.User;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Map;

/**
 * 数据过滤处理
 *
 * @author ruoyi
 */
@Aspect
@Component
public class DataScopeAspect {

    @Autowired
    private HttpSession httpSession;

    private static final String ADMIN = "admin";

    public static final String DATA_SCOPE = "dataScope";

    // 配置织入点
    @Pointcut("@annotation(com.qlu.syq.aspectj.DataScope)")
    public void dataScopePointCut() {
    }

    @Before("dataScopePointCut()")
    public void doBefore(JoinPoint point) throws NoSuchMethodException {
        handleDataScope(point);
    }

    protected void handleDataScope(final JoinPoint joinPoint) throws NoSuchMethodException {
        // 获得注解
        DataScope controllerDataScope = getAnnotation(joinPoint);
        if (controllerDataScope == null) {
            return;
        }
        // 获取当前的用户
        User user = (User) httpSession.getAttribute("admin");

        if (user != null) {
            // 如果是超级管理员，则不过滤数据
            if (!ADMIN.equals(user.getUsername())) {
                dataScopeFilter(joinPoint, user, controllerDataScope.alias());
            }
        }
    }

    /**
     * 数据范围过滤
     *
     * @param joinPoint 切点
     * @param user      用户
     */
    public static void dataScopeFilter(JoinPoint joinPoint, User user, String alias) {
        StringBuilder sqlString = new StringBuilder();

        Long value = user.getFloorId();

        sqlString.append(StrFormatter.format(" {}.id = {} ", alias, value));

        if (StringUtils.isNotBlank(sqlString.toString())) {
            Object params = joinPoint.getArgs()[0];
            if (params instanceof BaseEntity) {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString + ")");
            } else if (params instanceof Map) {
                ((Map<String, Object>) params).put(DATA_SCOPE, " AND (" + sqlString + ")");
            }
        }
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private DataScope getAnnotation(JoinPoint joinPoint) throws NoSuchMethodException {
//        Signature signature = joinPoint.getSignature();
//        MethodSignature methodSignature = (MethodSignature) signature;
//        Method method = methodSignature.getMethod();
//
//        if (method != null) {
//            return method.getAnnotation(DataScope.class);
//        }
//        return null;

        // 获取方法签名
        Signature signature = joinPoint.getSignature();
        Method method = ((MethodSignature) signature).getMethod();

        // 这个方法才是目标对象上有注解的方法（解决事务的代理方法获取不到注解）
        Method realMethod = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), method.getParameterTypes());
        return realMethod.getAnnotation(DataScope.class);
    }
}
